package com.tianjin.weight.service.pc;

import com.tianjin.weight.behaviour.base.PermissionBehavior;
import com.tianjin.weight.behaviour.base.RoleBehavior;
import com.tianjin.weight.behaviour.base.UserAuthBehavior;
import com.tianjin.weight.constants.Constant;
import com.tianjin.weight.entity.SysUser;
import com.tianjin.weight.exception.BusinessException;
import com.tianjin.weight.exception.code.BaseResponseCode;
import com.tianjin.weight.service.base.UserAuthService;
import com.tianjin.weight.utils.JwtTokenUtil;
import com.tianjin.weight.utils.MapperBeanUtils;
import com.tianjin.weight.utils.ServiceBeanUtils;
import com.tianjin.weight.vo.req.LoginReqVO;
import com.tianjin.weight.vo.resp.LoginRespVO;
import com.tianjin.weight.vo.resp.UserLoginAppRespVO;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class UserAuthWithPcService extends UserAuthService {
    public UserAuthWithPcService(UserAuthBehavior userAuthBehavior, PermissionBehavior permissionBehavior, RoleBehavior roleBehavior) {
        super(userAuthBehavior, permissionBehavior, roleBehavior);
    }

    @Override
    public String refreshToken(String refreshToken, String accessToken) throws Exception {
        if(ServiceBeanUtils.getRedisService().hasKey(Constant.JWT_ACCESS_TOKEN_BLACKLIST+refreshToken)||!JwtTokenUtil.validateToken(refreshToken)){
            throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
        }
        Long userId=JwtTokenUtil.getUserId(refreshToken);
        SysUser sysUser = MapperBeanUtils.getSysUserMapper().selectByPrimaryKey(userId);
        if (null==sysUser){
            throw new BusinessException(BaseResponseCode.TOKEN_PARSE_ERROR);
        }
        Map<String,Object> claims=null;

        if(ServiceBeanUtils.getRedisService().hasKey(Constant.JWT_REFRESH_KEY+userId)){
            claims=new HashMap<>();
            claims.put(Constant.JWT_PERMISSIONS_KEY,permissionBehavior.getPermissionsByUserId(userId));
            claims.put(Constant.JWT_ROLES_KEY,roleBehavior.getRoleNames(userId));
        }
        String newAccessToken=JwtTokenUtil.refreshToken(refreshToken,claims);

        ServiceBeanUtils.getRedisService().setifAbsen(Constant.JWT_REFRESH_STATUS+accessToken,userId,1, TimeUnit.MINUTES);


        if(ServiceBeanUtils.getRedisService().hasKey(Constant.JWT_REFRESH_KEY+userId)){
            ServiceBeanUtils.getRedisService().set(Constant.JWT_REFRESH_IDENTIFICATION+newAccessToken,userId,ServiceBeanUtils.getRedisService().getExpire(Constant.JWT_REFRESH_KEY+userId,TimeUnit.MILLISECONDS),TimeUnit.MILLISECONDS);
        }
        return newAccessToken;
    }

    @Override
    public List<UserLoginAppRespVO> getUserLoginInfo(Long userId) throws Exception {
        return this.userAuthBehavior.getUserLoginInfo(userId);
    }

    @Override
    public LoginRespVO login(LoginReqVO vo) throws Exception {
        Boolean flag = this.userAuthBehavior.logging(vo);
        SysUser sysUser = MapperBeanUtils.getSysUserMapper().getUserInfoByName(vo.getUsername());
        if (flag) {
            LoginRespVO respVO = LoginRespVO.builder()
                    .id(sysUser.getId())
                    .username(sysUser.getUsername())
                    .phone(sysUser.getPhone())
                    .realName(sysUser.getRealName())
                    .nickName(sysUser.getNickName())
                    .headPortrait(sysUser.getHeadPortrait())
                    .email(sysUser.getEmail())
                    .status(sysUser.getStatus())
                    .sex(sysUser.getSex())
                    .remark(sysUser.getRemark())
                    .startTime(sysUser.getStartTime())
                    .lastTime(sysUser.getLastTime())
                    .createTime(sysUser.getCreateTime())
                    .updateTime(sysUser.getUpdateTime())
                    .build();
            Map<String, Object> claims = new HashMap<>();
            claims.put(Constant.JWT_PERMISSIONS_KEY, permissionBehavior.getPermissionsByUserId(sysUser.getId()));
            claims.put(Constant.JWT_ROLES_KEY, roleBehavior.getRoleNames(sysUser.getId()));
            claims.put(Constant.JWT_USER_NAME, sysUser.getUsername());
            String access_token = JwtTokenUtil.getAccessToken(sysUser.getId(), claims);
            String refresh_token;
            refresh_token = JwtTokenUtil.getRefreshToken(sysUser.getId(), claims);
            respVO.setAccessToken(access_token);
            respVO.setRefreshToken(refresh_token);
            respVO.setUsername(sysUser.getNickName());
            respVO.setHeadPortrait(sysUser.getHeadPortrait());
//            respVO.setDept(sysUser.getDeptName());
            respVO.setCode(Constant.RESPONSE_CODE);
            respVO.setMsg(Constant.RESPONSE_LOGIN_MSG);
            return respVO;
        }
        else{
            return null;
        }
    }

    @Override
    public Boolean logging(LoginReqVO vo) throws Exception {
        return null;
    }

    @Override
    public void logout(String accessToken, String refreshToken) throws Exception {
        this.userAuthBehavior.logout(accessToken,refreshToken);
    }
}
